package com.edu.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.edu.common.core.domain.entity.SysUser;
import com.edu.common.utils.DateUtils;
import com.edu.common.utils.SecurityUtils;
import com.edu.domain.*;
import com.edu.mapper.ControlLimitMapper;
import com.edu.service.IControlLimitService;
import com.edu.system.domain.*;
import com.edu.system.domain.vo.ViewVisibleVo;
import com.edu.system.service.IMqJobService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 数据可见范围Service业务层处理
 *
 * @author zqq
 * @date 2023-01-23
 */
@Service
public class ControlLimitServiceImpl implements IControlLimitService
{
    @Autowired
    private ControlLimitMapper controlLimitMapper;

    @Autowired
    private IMqJobService mqJobService;


    /**
     * 查询数据可见范围
     *
     * @param id 数据可见范围主键
     * @return 数据可见范围
     */
    @Override
    public ControlLimit selectVisibleHomeById(Long id)
    {
        return controlLimitMapper.selectVisibleHomeById(id);
    }

    /**
     * 查询数据可见范围列表
     *
     * @param conditions 数据可见范围
     * @return 数据可见范围
     */
    @Override
    public List<ControlLimit> selectVisibleHomeList(Map<String,Object> conditions)
    {
        if (conditions.containsKey("scopeIds")){
            List<String> homeIds = new ArrayList<>();
            homeIds.add(SecurityUtils.getUserId());
            for (String scopeId  : (Set<String>) conditions.get("scopeIds")){
                homeIds.add(scopeId);
            }
            conditions.put("homeIds",homeIds);
            conditions.remove("scopeIds");
        }
        List<ControlLimit> list = controlLimitMapper.selectVisibleHomeList(conditions);
        return list;
    }

    @Override
    public Map<String,List<ControlLimit>> getVisibleScopeList(Map<String,Object> conditions){
        List<ControlLimit> list = controlLimitMapper.selectVisibleHomeManageList(conditions);

        List<ControlLimit> deptList = new ArrayList<>();
        List<ControlLimit> userList = new ArrayList<>();
        boolean isAll = false;

        if (!list.isEmpty()) {
            for (ControlLimit value : list) {
                if (value.getScopeType().equals("dept")) {
                    if (value.getHomeId().equals("1")) {
                        isAll = true;
                        deptList.clear();
                        deptList.add(value);
                        break;
                    }
                    deptList.add(value);
                } else if (value.getScopeType().equals("user")) {
                    userList.add(value);
                }
            }
        }

        if (isAll) {
            userList.clear();
        }
        Map<String,List<ControlLimit>> viewData = new HashMap<>();
        viewData.put("deptList",deptList);
        viewData.put("userList",userList);
        return viewData;
    }

    @Override
    public Map<String,Object> selectVisibleHomeManageList(Map<String,Object> conditions)
    {
        List<ControlLimit> list = controlLimitMapper.selectVisibleHomeManageList(conditions);
        Map<String, List<ViewVisibleVo>> viewRequired = new HashMap<>();
        boolean required = true;

        if (!list.isEmpty()) {
            for (ControlLimit value : list) {
                ViewVisibleVo viewVisible = new ViewVisibleVo();
                viewVisible.setType(value.getScopeType());
                viewVisible.setUuid(value.getHomeId());
                viewVisible.setShowName(value.getName());
                if (value.getScopeType().equals("dept") && value.getHomeId().equals("1")) {
                    required = false;
                    viewRequired.clear();
                    viewRequired.put("dept", new ArrayList<>(Collections.singletonList(viewVisible)));
                }

                if (required) {
                    if (value.getScopeType().equals("dept")) {
                        viewRequired.computeIfAbsent("dept", k -> new ArrayList<>()).add(viewVisible);
                    } else if (value.getScopeType().equals("user")) {
                        viewRequired.computeIfAbsent("user", k -> new ArrayList<>()).add(viewVisible);
                    } else if (value.getScopeType().equals("post")) {
                        viewRequired.computeIfAbsent("post", k -> new ArrayList<>()).add(viewVisible);
                    }
                }
            }
        }
        Map<String,Object> viewData = new HashMap<>();
        viewData.put("viewRequired",viewRequired);
        return viewData;
    }


    @Override
    public List<ControlLimitScope> selectVisibleList(String companyId,String table)
    {
        return controlLimitMapper.selectVisibleList(companyId,table);
    }

    @Override
    public List<KnowledgeControlLimit> selectVisibleCourseHomeList(Map<String,Object> conditions)
    {
        if (conditions.containsKey("scopeIds")){
            List<String> homeIds = new ArrayList<>();
            homeIds.add(SecurityUtils.getUserId());
            for (String scopeId  : (Set<String>) conditions.get("scopeIds")){
                homeIds.add(scopeId);
            }
            conditions.put("homeIds",homeIds);
            conditions.remove("scopeIds");
        }
        List<KnowledgeControlLimit> list = controlLimitMapper.selectVisibleCourseHomeList(conditions);
        return list;
    }

    @Override
    public KnowledgeControlLimit selectVisibleCourseHomeInfo(Map<String,Object> conditions)
    {
        if (conditions.containsKey("scopeIds")){
            List<String> homeIds = new ArrayList<>();
            homeIds.add(SecurityUtils.getUserId());
            for (String scopeId  : (Set<String>) conditions.get("scopeIds")){
                homeIds.add(scopeId);
            }
            conditions.put("homeIds",homeIds);
            conditions.remove("scopeIds");
        }
        KnowledgeControlLimit info = controlLimitMapper.selectVisibleCourseHomeInfo(conditions);
        return info;
    }

    /**
     * 查询数据可见范围列表
     *
     * @param conditions 数据可见范围
     * @return 数据可见范围
     */
    @Override
    public int selectVisibleHomeCount(Map<String,Object> conditions)
    {
        if (conditions.containsKey("scopeIds")){
            List<String> homeIds = new ArrayList<>();
            homeIds.add(SecurityUtils.getUserId());
            for (String scopeId  : (Set<String>) conditions.get("scopeIds")){
                homeIds.add(scopeId);
            }
            conditions.put("homeIds",homeIds);
            conditions.remove("scopeIds");
        }
        return controlLimitMapper.selectVisibleHomeCount(conditions);
    }

    @Override
    public int selectVisibleHomeJoinCount(Map<String,Object> conditions)
    {
        if (conditions.containsKey("scopeIds")){
            List<String> homeIds = new ArrayList<>();
            homeIds.add(SecurityUtils.getUserId());
            for (String scopeId  : (Set<String>) conditions.get("scopeIds")){
                homeIds.add(scopeId);
            }
            conditions.put("homeIds",homeIds);
            conditions.remove("scopeIds");
        }
        return controlLimitMapper.selectVisibleHomeJoinCount(conditions);
    }

    /**
     * 新增数据可见范围
     *
     * @param assignUserData 数据可见范围
     * @return 结果
     */
    @Override
    @Transactional
    public void insertVisibleHome(Map<String,Object> assignUserData)
    {
        SysUser userInfo = SecurityUtils.getLoginUser();
        String userId = userInfo.getUserId();
        String companyId = userInfo.getCompanyId();
        String companyName = userInfo.getCompanyName();
        String module = (String) assignUserData.get("module");
        String targetId = (String) assignUserData.get("targetId");
        String targetTitle = (String) assignUserData.get("targetTitle");
        String model = (String) assignUserData.get("model");
        String required = (String) assignUserData.get("data");
        String table = module + "_visible";
        String time  = DateUtils.getTime();
        List<ControlLimit> insertData = new ArrayList<>();
        if (model.equals("2")) {
            JSONArray requiredArray = JSON.parseArray(required);
            for (int i = 0; i < requiredArray.size(); i++) {
                ControlLimit assignUser = new ControlLimit();
                JSONObject jsonObject = requiredArray.getJSONObject(i);
                String type   = jsonObject.getString("type");
                String deptId = jsonObject.getString("uuid");
                String deptName = jsonObject.getString("showName");
                assignUser.setHomeId(deptId);
                assignUser.setName(deptName);
                assignUser.setScopeType(type);
                assignUser.setTargetId(targetId);
                assignUser.setTargetTitle(targetTitle);
                assignUser.setIsDelete(0);
                assignUser.setCreateTime(time);
                assignUser.setUpdateTime(time);
                assignUser.setCreateUserId(userId);
                assignUser.setUpdateUserId(userId);
                assignUser.setCompanyId(companyId);
                insertData.add(assignUser);
            }
        } else if (model.equals("1")) {
            Set<String> scopeIds = userInfo.getScopeIds();
            if (scopeIds.contains("1")){
                ControlLimit assignUser = new ControlLimit();
                assignUser.setHomeId("1");
                assignUser.setName(companyName);
                assignUser.setScopeType("dept");
                assignUser.setTargetId(targetId);
                assignUser.setTargetTitle(targetTitle);
                assignUser.setIsDelete(0);
                assignUser.setCreateTime(time);
                assignUser.setUpdateTime(time);
                assignUser.setCreateUserId(userId);
                assignUser.setUpdateUserId(userId);
                assignUser.setCompanyId(companyId);
                insertData.add(assignUser);
            } else {
                for (String homeId : scopeIds){
                    ControlLimit assignUser = new ControlLimit();
                    assignUser.setHomeId(homeId);
                    assignUser.setName(companyName);
                    assignUser.setScopeType("dept");
                    assignUser.setTargetId(targetId);
                    assignUser.setTargetTitle(targetTitle);
                    assignUser.setIsDelete(0);
                    assignUser.setCreateTime(time);
                    assignUser.setUpdateTime(time);
                    assignUser.setCreateUserId(userId);
                    assignUser.setUpdateUserId(userId);
                    assignUser.setCompanyId(companyId);
                    insertData.add(assignUser);
                }
            }
        }
        //先硬删掉$module_visible里面的数据
        Map<String,Object> conditions = new HashMap<>();
        conditions.put("targetId",targetId);
        conditions.put("table",table);
        conditions.put("companyId",companyId);
        controlLimitMapper.deleteVisibleHomeById(conditions);

        if (insertData.size() > 0){
            controlLimitMapper.insertVisibleHomeAll(insertData,table);
        }
    }

    @Override
    public int insertVisibleHomeAll(List<ControlLimit> insertData, String table){
       return controlLimitMapper.insertVisibleHomeAll(insertData,table);
    }

    @Override
    public void publishVisibleHome(String targetId,String targetTitle,String module,String model){
        SysUser userInfo = SecurityUtils.getLoginUser();
        String userId = userInfo.getUserId();
        String companyId = userInfo.getCompanyId();
        String companyName = userInfo.getCompanyName();
        String time = DateUtils.getTime();
        Map<String,Object> conditions = new HashMap<>();
        conditions.put("table",module + "_visible");
        conditions.put("targetId",targetId);
        conditions.put("companyId",companyId);
        int count = controlLimitMapper.selectVisibleHomeCount(conditions);
        if (count == 0){
            List<ControlLimit> insertData = new ArrayList<>();
            if (model.equals("1")){
                Set<String> scopeIds = userInfo.getScopeIds();
                if (scopeIds.contains("1")){
                    ControlLimit assignUser = new ControlLimit();
                    assignUser.setHomeId("1");
                    assignUser.setName(companyName);
                    assignUser.setScopeType("dept");
                    assignUser.setTargetId(targetId);
                    assignUser.setTargetTitle(targetTitle);
                    assignUser.setIsDelete(0);
                    assignUser.setCreateTime(time);
                    assignUser.setUpdateTime(time);
                    assignUser.setCreateUserId(userId);
                    assignUser.setUpdateUserId(userId);
                    assignUser.setCompanyId(companyId);
                    insertData.add(assignUser);
                } else {
                    for (String homeId : scopeIds){
                        ControlLimit assignUser = new ControlLimit();
                        assignUser.setHomeId(homeId);
                        assignUser.setName(companyName);
                        assignUser.setScopeType("dept");
                        assignUser.setTargetId(targetId);
                        assignUser.setTargetTitle(targetTitle);
                        assignUser.setIsDelete(0);
                        assignUser.setCreateTime(time);
                        assignUser.setUpdateTime(time);
                        assignUser.setCreateUserId(userId);
                        assignUser.setUpdateUserId(userId);
                        assignUser.setCompanyId(companyId);
                        insertData.add(assignUser);
                    }
                }
            }
            if (insertData.size() > 0){
                controlLimitMapper.insertVisibleHomeAll(insertData,module + "_visible");
            }
        }
        if (!module.equals("knowledge")){
            //使用队列处理必修学习
            MqJob jobData = new MqJob();
            jobData.setUuid(UUID.randomUUID().toString());
            jobData.setTargetId(targetId);
            jobData.setTargetTitle(targetTitle);
            jobData.setModule(module);
            jobData.setAction("AssignUser");
            jobData.setStatus(0);
            jobData.setCreateTime(time);
            jobData.setUpdateTime(time);
            jobData.setCreateUserId(userId);
            jobData.setUpdateUserId(userId);
            jobData.setCompanyId(companyId);
            mqJobService.insertMqJob(jobData);
        }
    }

    /**
     * 修改数据可见范围
     *
     * @param controlLimit 数据可见范围
     * @return 结果
     */
    @Override
    public int updateVisibleHome(ControlLimit controlLimit)
    {
        controlLimit.setUpdateTime(DateUtils.getTime());
        return controlLimitMapper.updateVisibleHome(controlLimit);
    }

    /**
     * 批量删除数据可见范围
     *
     * @param ids 需要删除的数据可见范围主键
     * @return 结果
     */
    @Override
    public int deleteVisibleHomeByIds(Long[] ids)
    {
        return controlLimitMapper.deleteVisibleHomeByIds(ids);
    }

    /**
     * 删除数据可见范围信息
     *
     * @param conditions 数据可见范围主键
     * @return 结果
     */
    @Override
    public int deleteVisibleHomeById(Map<String,Object> conditions)
    {
        return controlLimitMapper.deleteVisibleHomeById(conditions);
    }
}
